﻿using System;
using System.Collections.Generic;
using System.Data;

namespace Agile.DataAccess
{
    /// <summary>
    /// 
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
	public interface IQueryBuilder<TEntity>
	{
        /// <summary>
        /// 
        /// </summary>
		QueryBuilderData Data { get; set; }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
		IQueryBuilder<TEntity> Select(string sql);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
		IQueryBuilder<TEntity> From(string sql);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
		IQueryBuilder<TEntity> Where(string sql);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
		IQueryBuilder<TEntity> AndWhere(string sql);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
		IQueryBuilder<TEntity> OrWhere(string sql);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
		IQueryBuilder<TEntity> GroupBy(string sql);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
		IQueryBuilder<TEntity> OrderBy(string sql);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
		IQueryBuilder<TEntity> Having(string sql);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="currentPage"></param>
        /// <param name="itemsPerPage"></param>
        /// <returns></returns>
		IQueryBuilder<TEntity> Paging(int currentPage, int itemsPerPage);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <param name="value"></param>
        /// <param name="parameterType"></param>
        /// <param name="direction"></param>
        /// <param name="size"></param>
        /// <returns></returns>
		IQueryBuilder<TEntity> Parameter(string name, object value, DataTypes parameterType = DataTypes.Object, ParameterDirection direction = ParameterDirection.Input, int size = 0);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="parameters"></param>
        /// <returns></returns>
		IQueryBuilder<TEntity> Parameters(params object[] parameters);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="customMapper"></param>
        /// <returns></returns>
		List<TEntity> QueryMany(Action<TEntity, IDataReader> customMapper = null);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="customMapper"></param>
        /// <returns></returns>
		List<TEntity> QueryMany(Action<TEntity, dynamic> customMapper);
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="TList"></typeparam>
        /// <param name="customMapper"></param>
        /// <returns></returns>
		TList QueryMany<TList>(Action<TEntity, IDataReader> customMapper = null) where TList : IList<TEntity>;
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="TList"></typeparam>
        /// <param name="customMapper"></param>
        /// <returns></returns>
		TList QueryMany<TList>(Action<TEntity, dynamic> customMapper) where TList : IList<TEntity>;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="list"></param>
        /// <param name="customMapper"></param>
		void QueryComplexMany(IList<TEntity> list, Action<IList<TEntity>, IDataReader> customMapper);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="list"></param>
        /// <param name="customMapper"></param>
		void QueryComplexMany(IList<TEntity> list, Action<IList<TEntity>, dynamic> customMapper);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="customMapper"></param>
        /// <returns></returns>
		TEntity QuerySingle(Action<TEntity, IDataReader> customMapper = null);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="customMapper"></param>
        /// <returns></returns>
		TEntity QuerySingle(Action<TEntity, dynamic> customMapper);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="customMapper"></param>
        /// <returns></returns>
		TEntity QueryComplexSingle(Func<IDataReader, TEntity> customMapper);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="customMapper"></param>
        /// <returns></returns>
		TEntity QueryComplexSingle(Func<dynamic, TEntity> customMapper);
	}
}
